//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#include "Graphics/Loaders/TextureLoader.h"

namespace Engine
{
namespace Graphics
{

#	include "Shared/Resources/ImageHeader.h"
	
	
/*
=================================================
	constructor
=================================================
*/
	TextureLoader::TextureLoader ()
	{
	}
		
/*
=================================================
	Register
=================================================
*/
	void TextureLoader::Register (ResourceManager *rm)
	{
		rm->RegisterLoader( EResource::TEXTURE, Load, null, this );
	}
	
/*
=================================================
	Unregister
=================================================
*/
	void TextureLoader::Unregister (ResourceManager *rm)
	{
		rm->UnregisterLoader( EResource::TEXTURE, Load, null, this );
	}

/*
=================================================
	Load
=================================================
*/
	bool TextureLoader::Load (ResourcePtr &resource, const RFilePtr &file, void *parameter,
							  const Resource::ResLoadParams &loadParams, const EngineSubSystemsRef ess)
	{
		CHECK_ERR( loadParams.Is< Texture::TexLoadParams >() );

		TexturePtr	tex = Texture::New( ess );
		CHECK_ERR( _LoadTex( tex, file, parameter, loadParams.To< Texture::TexLoadParams >(), ess ) );

		resource = tex;
		return true;
	}
	
/*
=================================================
	_LoadTex
=================================================
*/
	bool TextureLoader::_LoadTex (const TexturePtr &tex, const RFilePtr &file, void *parameter,
								  const Texture::TexLoadParams &loadParams, const EngineSubSystemsRef ess)
	{
		typedef array< ImageHeader::MipmapInfo, TFastCopyStrategy< ImageHeader::MipmapInfo > >	mipmap_info_array_t;

		CHECK_ERR( tex.IsNotNull() );

		RESFILE_CHECK_HEADER( file, TextureFileInfo );

		ImageHeader			header;
		mipmap_info_array_t	mipmaps;
		binary_array_t		data;
		bool				res = true;

		res &= file->Read( header );

		mipmaps.Resize( header.mipmaps, false );
		res &= file->Read( mipmaps.ptr(), mipmaps.Size() );
		
		CHECK_ERR( res );


		usize	pos			= file->Pos();
		uvec3	dim			= uvec3( header.width, header.height, header.depth );
		uint	max_mipmaps	= UXMathExt::GetNumberOfMipmaps( dim ) + 1;

		data.Resize( mipmaps.Front().size, false );


		FOR( i, mipmaps )
		{
			file->SeekSet( pos + mipmaps[i].offset );

			CHECK_ERR( file->Read( data.ptr(), mipmaps[i].size ) );

			CHECK_ERR( tex->SetImage( dim, (EPixelFormat::type) header.pixelFormat, mipmaps[i].level,
										 uni_binbuffer_t( data.ptr(), mipmaps[i].size ) ) );
		}

		if ( max_mipmaps > (uint)header.mipmaps and
			 loadParams.generateMipmaps )
		{
			tex->GenerateMipmaps();
		}

		tex->SetSampler( loadParams.sampler );
		
		tex->_memSize = data.Size();
		return true;
	}


}	// Graphics
}	// Engine